package cn.open.feishu.alert.support.Handler;

import cn.open.feishu.alert.common.enums.AlertTypeEnum;
import cn.open.feishu.alert.common.model.CardAlertRequest;
import cn.open.feishu.alert.common.model.PrivateCardAlertRequest;
import cn.open.feishu.alert.common.model.PrivateCardAlertResponse;
import cn.open.feishu.alert.common.param.CardDirectAlertParam;
import cn.open.feishu.alert.common.utils.HttpUtil;
import cn.open.feishu.alert.common.utils.TimeUtil;
import cn.open.feishu.alert.config.ButtonProperties;
import cn.open.feishu.alert.config.FeiShuProperties;
import cn.open.feishu.alert.support.FeishuAlertClient;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.cache.Cache;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.env.Environment;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static cn.open.feishu.alert.common.FeishuConstant.SUCCESS_CODE;


/**
 * @Description 飞书消息直接告警处理器
 * @Author fandy.lin
 * @Date 2021/11/26 2:10 下午
 **/
@Slf4j
public class PrivateFeishuDirectAlertHandler extends BaseFeishuAlertHandler implements FeishuDirectAlertHandler {
    private Cache<String, String> userCache;

    public PrivateFeishuDirectAlertHandler(Environment env, FeiShuProperties feiShuProperties, ButtonProperties buttonProperties, FeishuAlertClient feishuAlertClient, Cache<String,String> userCache) {
        super(env, feiShuProperties, buttonProperties, feishuAlertClient);
        this.userCache = userCache;
    }

    @Override
    public void send(CardDirectAlertParam param) {
        String realSendUrl = feiShuProperties.getAppSendUrl();
        CardAlertRequest alertReq = null;
        try {
            //获得用户Id
            List<String> userIds = getUserIdList(param.getEmails());
            //构建卡片请求
            alertReq = buildCardRequest(param.getTitle(), param.getTimestamp(), param.getContent(),param.getLinkList(),userIds);
            //获取token缓存
            Map<String, String> tokenMap = feishuAlertClient.getTokenMap();
            if(Objects.isNull(alertReq) && Objects.isNull(tokenMap)){
                log.warn("feishu alert:send direct private alert fail,alertReq={},tokenMap={}",alertReq,tokenMap);
                return;
            }
            //发送告警消息
            PrivateCardAlertResponse alertResp = HttpUtil.execute(realSendUrl, tokenMap, alertReq, PrivateCardAlertResponse.class);
            if (SUCCESS_CODE != alertResp.getCode()) {
                log.warn("feishu alert:send direct private alert fail,ret code={},msg={}", alertResp.getCode(), alertResp.getCode());
            }
        } catch (IOException e) {
            log.error("feishu alert:send direct private alert error,send url={},req={}", realSendUrl, JSON.toJSONString(alertReq), e);
        }
    }

    private List<String> getUserIdList(List<String> emails) {
        List<String> notCacheEmails = new ArrayList<>();
        List<String> cacheUserIds = Lists.newArrayListWithExpectedSize(emails.size());
        emails.stream().forEach(email->{
            if(Objects.isNull(userCache.getIfPresent(email))){
                notCacheEmails.add(email);
            }else{
                cacheUserIds.add(userCache.getIfPresent(email));
            }
         });
        if(Objects.isNull(notCacheEmails)){
            return cacheUserIds;
        }
        Map<String, String> userMap = feishuAlertClient.findUserMap(notCacheEmails);
        userMap.entrySet().forEach(user->{
            userCache.put(user.getKey(),user.getValue());
            cacheUserIds.add(user.getValue());
        });
        return cacheUserIds;
    }

    private CardAlertRequest buildCardRequest(String title, Long timestamp, String content, List<CardDirectAlertParam.Link> linkList, List<String> userIds) {
        List<CardAlertRequest.Element> elements = new ArrayList<>();
        elements.add(buildCardText(title,timestamp,content));
        buildButtonList(elements, linkList);
        CardAlertRequest.Card card = new CardAlertRequest.Card(elements, buildCardHeader(AlertTypeEnum.TEXT_NOTIFICATION));
        return new PrivateCardAlertRequest("interactive",card,userIds);
    }

    private CardAlertRequest.Element buildCardText(String title,Long timestamp, String content) {
        StringBuilder textBulider = new StringBuilder();
        if(!StringUtils.isEmpty(title)){
            textBulider.append("\n**消息名称:**\n").append(title);
        }
        if(Objects.nonNull(timestamp)){
            textBulider.append("\n**消息时间:**\n").append(TimeUtil.dateFormat(timestamp));
        }
        if(!StringUtils.isEmpty(content)){
            textBulider.append("\n**消息内容:**\n").append(content);
        }
        JSONObject text = new JSONObject();
        text.put("content", textBulider.toString());
        text.put("tag", "lark_md");
        return CardAlertRequest.Element.builder().tag("div").text(text).build();
    }

    private void buildButtonList(List<CardAlertRequest.Element> elementList, List<CardDirectAlertParam.Link> linkList) {
        if(CollectionUtils.isEmpty(linkList)){
            return;
        }
        List<JSONObject> buttonList = new ArrayList<>();
        for(CardDirectAlertParam.Link link:linkList){
            buttonList.add(buildButton(link.getName(),link.getUrl()));
        }
        CardAlertRequest.Element hr = CardAlertRequest.Element.builder().tag("hr").build();
        CardAlertRequest.Element actions = CardAlertRequest.Element.builder().tag("action").actions(buttonList).build();
        elementList.add(hr);
        elementList.add(actions);
    }
}